package cz.possoft.serializable.piskvorky.game;

import cz.possoft.generic.utils.GenericUtils;
import cz.possoft.serializable.generic.HraciPole;


/**  
  *
  * Hraci pole pro hru piskvorky.
  * 
  * @author mara
  */
public class PiskvorkyPole extends HraciPole {
	
	public static final int POCET_CTVERCU = 31; 
		
	public static final long serialVersionUID = 195649945;
	
	private PiskvorkyFigurka figurky[][];
	
    public PiskvorkyPole(boolean novaHra) {  
    	setFigurky(new PiskvorkyFigurka[POCET_CTVERCU][POCET_CTVERCU]);
        loadFigurkyAfterNewGame();
    }  
    
    public PiskvorkyFigurka[][] getFigurky() {
        return figurky;
    }

    public void setFigurky(PiskvorkyFigurka[][] figurky) {
        this.figurky = figurky;
    }    
    
    public PiskvorkyFigurka getFigurka(int x, int y) {
        return figurky[x][y];	
    }
    
    public void setFigurka(int x, int y, PiskvorkyFigurka figurka) {
        figurky[x][y] = figurka;	
    }    
    
    // Pocatecni nacteni figurek na sachovnici po startu nove hry
    private void loadFigurkyAfterNewGame() {
    	for (int i=0 ; i<POCET_CTVERCU ; i++)
    		for (int j=0 ; j<POCET_CTVERCU ; j++) {
    			figurky[i][j] = new PiskvorkyFigurka(i, j, this);
    		}
    }
    
    // zkontroluje jestli nejaky hrac vyhral - ma 4 v rade.
    // Vraci barvu tohoto hrace nebo 0 pro hru ve stavu nekoncovem.        
    public int controlGameEnd() {    	
    	return new GameEndController().controlGameEnd();
    }
    
    // trida pouzita pri kontrole konce hry
    private class GameEndController {        
    	
    	int blackCounter = 0;
    	int whiteCounter = 0;
    	int color;
    	
        // zkontroluje jestli nejaky hrac vyhral - ma 4 v rade.
        // Vraci barvu tohoto hrace nebo 0 pro hru ve stavu nekoncovem.
        private int controlGameEnd() {        	
        	blackCounter = 0;
        	whiteCounter = 0;
        	boolean checkFlag = true;
        	
        	//System.out.println("KONTROLA SVISLA");
        	// kontrola svislych stran
        	for (int i=0 ; i<POCET_CTVERCU ; i++) {  
        		if (checkFlag) {
         		   blackCounter = 0;
         		   whiteCounter = 0;
         		}        		
        		for (int j=0 ; j<POCET_CTVERCU ; j++) {
        			if (checkFlag) {
        			   color = figurky[i][j].getColor();        			   
                       if (checkCounter()) {
                    	   // oznaceni viteznych figurek
                    	   for (int k=0; k<5 ; k++) {
                    	       figurky[i][j-k].setPartOfWinningLine(true);
                    	   }
                    	   checkFlag = false;
                       }
                       //System.out.println("x:" + i + ", y:" + j + ", bc:" + blackCounter + ", wc:" + whiteCounter);
        			}
        		}
        	}
        	if (blackCounter == 5) return GenericUtils.COLOR_BLACK;
        	if (whiteCounter == 5) return GenericUtils.COLOR_WHITE;
        	
        	//System.out.println("KONTROLA VODOROVNA");
           	// kontrola vodorovnych stran
        	for (int i=0 ; i<POCET_CTVERCU ; i++) {
        		if (checkFlag) {
        		   blackCounter = 0;
        		   whiteCounter = 0;
        		}
        		for (int j=0 ; j<POCET_CTVERCU ; j++) {
        			if (checkFlag) {
        			   color = figurky[j][i].getColor();
        			   if (checkCounter()) {
                       	   // oznaceni viteznych figurek
                    	   for (int k=0; k<5 ; k++) {
                    	       figurky[j-k][i].setPartOfWinningLine(true);
                    	   }        				   
        				   checkFlag = false;
        			   }
        			   //System.out.println("x:" + j + ", y:" + i + ", bc:" + blackCounter + ", wc:" + whiteCounter);                       
        			}
        		}
        	}
         	if (blackCounter == 5) return GenericUtils.COLOR_BLACK;
        	if (whiteCounter == 5) return GenericUtils.COLOR_WHITE;
        	
        	//System.out.println("KONTROLA UHLOPRICEK");
        	// kontrola uhlopricek  
        	int checkUhl = 0;
        	for (int i=0 ; i<POCET_CTVERCU-4 ; i++) {        		
        		for (int j=0 ; j<POCET_CTVERCU-4 ; j++) {        			
        				checkUhl = checkUhl(i, j, true);
        				if (checkUhl != GenericUtils.COLOR_NEUTRAL) return checkUhl;        			
        		}   
        	}
        	for (int i=4 ; i<POCET_CTVERCU ; i++) {        		
        		for (int j=0 ; j<POCET_CTVERCU-4 ; j++) {        			
        				checkUhl = checkUhl(i, j, false);
        				if (checkUhl != GenericUtils.COLOR_NEUTRAL) return checkUhl;        			
        		}   
        	}        	
        	return checkUhl;        	        	
         	//return GenericUtils.COLOR_NEUTRAL;
        }
        
        // provede zvyseni pocitadel a pripadne ohlasi konec hry
        private boolean checkCounter() {
   			if (color == GenericUtils.COLOR_NEUTRAL) {
				blackCounter = 0;
				whiteCounter = 0;
			}
			else if (color == GenericUtils.COLOR_BLACK) {
				blackCounter++;
				whiteCounter = 0;
			}
			else if (color == GenericUtils.COLOR_WHITE) {
				blackCounter = 0;
				whiteCounter++;    				
			}   			
   			if ((blackCounter == 5) || (whiteCounter == 5)) return true;
   			return false;
        }
        
        // zkontroluje zda je bod x,y pocatek uhloprickoveho ukonceni (kontrola uhlopricek z obou stran)
        private int checkUhl(int x, int y, boolean smer) {
        	color = figurky[x][y].getColor();
        	// pro neutralni barvu na x,y se metoda rovnou ukonci
        	if (color == GenericUtils.COLOR_NEUTRAL) {
        		return color;
        	}
        	// kontrola uhlopricky pro zvysujici se x aji y
        	if (smer == true) {
        	  for (int i=1; i<5 ; i++) {
        		  if (color != figurky[x+i][y+i].getColor()) {
        			  return GenericUtils.COLOR_NEUTRAL;
        		  }
        	  }
          	  // oznaceni viteznych figurek
       	      for (int k=0; k<5 ; k++) {
       	          figurky[x+k][y+k].setPartOfWinningLine(true);
       	      }
       	   }              	          	
        	
        	// kontrola uhlopricky pro zvysujici se y, snizujici se x
        	if (smer == false) {
        	  for (int i=1; i<5 ; i++) {
           		  if (color != figurky[x-i][y+i].getColor()) {
           			  return GenericUtils.COLOR_NEUTRAL;
        		  }        		
        	  }
         	  // oznaceni viteznych figurek
       	      for (int k=0; k<5 ; k++) {
       	          figurky[x-k][y+k].setPartOfWinningLine(true);
       	      }        	  
        	}
        	return color;
        }

    }
    

}
